package pl.edu.amu.kino.kardamon.engine;

import java.util.Vector;
import java.io.*;

/**
 *
 * @author Beriba
 */
public class Baza {

    private static Baza instance;
    private static Vector nazwyPrzystankowVector;
    private static Vector definicjeLiniiVector;
    private static Vector listaLiniiVector;
    private static Vector godzinyOdjazdowVector;

    private Baza() {
        nazwyPrzystankowVector = new Vector();
        definicjeLiniiVector = new Vector();
        listaLiniiVector = new Vector();
        godzinyOdjazdowVector = new Vector();

        try {
            InputStreamReader inputStreamTxt = null;
            inputStreamTxt = new InputStreamReader(getClass().getResourceAsStream("baza.txt"), "utf-8");

            StringBuffer buf = new StringBuffer();
            String[] listaLinii, tablicaNazwP, godzinyOdjazdu, nazwa;
            String listaLiniiString = "", godzinyOdjazduString = "";
            int c, s = 0;
            char bufChar;
            while ((c = inputStreamTxt.read()) != -1) {
                char ch = (char) c;
                if (ch == '\n') {
                    bufChar = buf.charAt(0);
                    if (bufChar == 48) {
                        tablicaNazwP = split(buf.toString(), " ");
                        nazwa = split(tablicaNazwP[2], "_");
                        nazwyPrzystankowVector.addElement(concatenateArray(nazwa));
                    } else if (bufChar == 49) {
                        listaLinii = split(buf.toString(), " ");
                        for (int i = 2; i < listaLinii.length; i++) {
                            listaLiniiString += listaLinii[i] + " ";
                        }
                        definicjeLiniiVector.addElement(new String(listaLiniiString.trim()));
                        if (listaLiniiVector.indexOf(listaLinii[2]) == -1) {
                            listaLiniiVector.addElement(listaLinii[2]);
                        }
                        listaLiniiString = "";
                    } else if (bufChar == 50) {
                        godzinyOdjazdu = split(buf.toString(), " ");
                        for (int i = 2; i < godzinyOdjazdu.length; i++) {
                            godzinyOdjazduString += godzinyOdjazdu[i] + " ";
                        }
                        godzinyOdjazdowVector.addElement(new String(godzinyOdjazduString.trim()));
                        godzinyOdjazduString = "";
                    }
                    buf.delete(0, buf.length());
                } else {
                    buf.append(ch);
                }
            }
            inputStreamTxt.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Vector getListeNazwPrzystankow() {
        return nazwyPrzystankowVector;
    }

    public Vector getListeLinii() {
        return listaLiniiVector;
    }

    public Vector getListeDefinicjiLinii() {
        return definicjeLiniiVector;
    }

    public String[] getListeGodzinOdjazduLinii(String idLinii) {

        String[] godziny = split((String)godzinyOdjazdowVector.elementAt(Integer.parseInt(idLinii)), " ");
        return godziny;
    }

    public String getIdPrzystanku(String nazwa) {
        return Integer.toString(nazwyPrzystankowVector.indexOf(nazwa));
    }

    public String getIdLinii(String nazwaLinii, String kierunek) {
        String[] definicja = {};
        String idLinii="", ostatPrzyst="";
        int defLen;
        for (int i = 0; i < definicjeLiniiVector.size(); i++) {
            definicja = split(definicjeLiniiVector.elementAt(i).toString(), " ");
            defLen = definicja.length;
            ostatPrzyst = nazwyPrzystankowVector.elementAt(Integer.parseInt(definicja[defLen - 1])).toString();
            if (definicja[0].equals(nazwaLinii) && ostatPrzyst.equals(kierunek)) {
                idLinii = Integer.toString(i);
            }
        }
        return idLinii;
    }

    public Vector getKierunkiLinii(String nazwaLinii) {
        String[] definicja = {};
        int defLen;
        Vector kier = new Vector();
        for (int i = 0; i < definicjeLiniiVector.size(); i++) {
            definicja = split(definicjeLiniiVector.elementAt(i).toString(), " ");
            if (definicja[0].equals(nazwaLinii)) {
                defLen = definicja.length;
                kier.addElement(nazwyPrzystankowVector.elementAt(Integer.parseInt(definicja[defLen - 1])));
            }
        }
        return kier;
    }

    public Vector getCzasyPrzejazduLinii(String idLinii) {
        String[] definicja;
        Vector czasyPrzejazduLiniiVector = new Vector();
        definicja = split(definicjeLiniiVector.elementAt(Integer.parseInt(idLinii)).toString(), " ");
        for (int i = 1; i < definicja.length; i++) {
            if (i % 2 == 0) {
                czasyPrzejazduLiniiVector.addElement(definicja[i]);
            }
        }
        return czasyPrzejazduLiniiVector;
    }

    public Vector getListePrzystankowNaLinii(String idLinii) {
        String[] definicja;
        Vector przystankiNaLiniiVector = new Vector();
        definicja = split(definicjeLiniiVector.elementAt(Integer.parseInt(idLinii)).toString(), " ");
        for (int i = 0; i < definicja.length; i++) {
            if (i % 2 == 1) {
                przystankiNaLiniiVector.addElement(nazwyPrzystankowVector.elementAt(Integer.parseInt(definicja[i])));
            }
        }
        return przystankiNaLiniiVector;
    }

    public String getNazwaLinii(String idLinii) {
        return nazwyPrzystankowVector.elementAt(Integer.parseInt(idLinii)).toString();
    }

    public Vector getListeLiniiNaPrzystanku(String przystanek) {
        Vector linie = new Vector();
        String[] definicja;
        String poczatek, koniec;
        String ostatni;
        for (int i = 0; i < definicjeLiniiVector.size(); i++) {
            definicja = split(definicjeLiniiVector.elementAt(i).toString(), " ");
            for (int j = 0; j < definicja.length; j++) {
                if (j > 0 && j % 2 == 1) {
                    if (definicja[j].equals(przystanek)) {
                        ostatni = (String) definicja[definicja.length - 1];
                        koniec = (String) nazwyPrzystankowVector.elementAt(Integer.parseInt((String) ostatni));
                        poczatek = (String) nazwyPrzystankowVector.elementAt(Integer.parseInt(definicja[1]));
                        linie.addElement(new Linia(definicja[0].toString(), poczatek, koniec));
                    }
                }
            }
        }

        return linie;
    }

    private static String[] split(String original, String separator) {
        Vector nodes = new Vector();
        // Parse nodes into vector
        int index = original.indexOf(separator);
        while (index >= 0) {
            nodes.addElement(original.substring(0, index));
            original = original.substring(index + separator.length());
            index = original.indexOf(separator);
        }
        // Get the last node
        nodes.addElement(original);

        // Create splitted string array
        String[] result = new String[nodes.size()];
        if (nodes.size() > 0) {
            for (int loop = 0; loop < nodes.size(); loop++) {
                result[loop] = (String) nodes.elementAt(loop);
            }
        }

        return result;
    }

    private static String concatenateArray(String[] array) {
        String arrayString = "";
        for (int i = 0; i < array.length; i++) {
            arrayString += array[i] + " ";
        }
        return arrayString.trim();
    }

    public static Baza getInstance() {
        if (instance == null) {
            instance = new Baza();
        }

        return instance;
    }
}
